package com.org.Filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.org.Msg.Msg;
import com.org.serviceImpl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.stereotype.Component;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

/**
 * 自定义请求过滤器，token没有或者不正确的时候，
 * 告诉用户执行相应操作，token正确且未认真的情况下则放行请求，
 * 交由认证过滤器进行认证操作
 */
public class OncePerRequestAuthoricationFilter extends BasicAuthenticationFilter {

    StringRedisTemplate stringRedisTemplate;
    UserServiceImpl userServiceImpl;

    Gson gson=new Gson();

    public OncePerRequestAuthoricationFilter(AuthenticationManager authenticationManager, StringRedisTemplate stringRedisTemplate, UserServiceImpl userServiceImpl) {
        super(authenticationManager);
        this.stringRedisTemplate=stringRedisTemplate;
        this.userServiceImpl=userServiceImpl;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String token=request.getHeader("token");
        if(token==null || token.equals("")){
            //token为空，则返回空
            chain.doFilter(request, response);
            return;
        }

        String username=stringRedisTemplate.opsForValue().get(token);
        try{
            //判断token情况，给予对应的处理方案
            if(username==null){
                throw new Exception("登录凭证不正确或者超时了,请重新登录！！！");
            }else{
                UserDetails userDetails = userServiceImpl.loadUserByUsername(username);
                if(userDetails!=null){
                    UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken=new UsernamePasswordAuthenticationToken(username,null,userDetails.getAuthorities());
                    response.setHeader("token",token);
                    SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
                }
            }
        }catch (Exception e){
            //抛出异常，并返回给前端
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/json; charset=utf-8");
            Msg msg= Msg.fail(e.getLocalizedMessage());
            response.getWriter().write(gson.toJson(msg));
            response.getWriter().flush();
            chain.doFilter(request, response);
            return;
        }
        super.doFilterInternal(request,response,chain);
    }
}
